using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using Hoshimi._Map_;


namespace Hoshimi._TSP_
{

    public enum CityDistanceMethod
    {
        Manhattan           = 1,
        Euclidean           = 2,
        EuclideanNoSQR      = 3,
        PathFinderDistance  = 4,
    }

    public class City
    {
        // VARIABLES
		public static PathFinderConfig mPathFinderConfig	= PathFinderConfig.Default;
        public Point mLocation								= Point.Empty;
        public static CityDistanceMethod mDistanceMethod	= CityDistanceMethod.Manhattan; 

        // GETTERS & SETTERS
        public static PathManager myPathManager    { get { return PathManager.getInstance(); } }


        // METHODES
        public static int sumDistance(List<City> nodes)
        {
            if (nodes.Count == 0)
                return 0;
            int dist = 0;

            City prev = nodes[0];
            for (int i = 1; i < nodes.Count; i++)
            {
                dist += prev.Distance(nodes[i]);
                prev = nodes[i];
            }
            return dist;
        }

        public virtual int Distance(City city)
        {
            if (this.mLocation == city.mLocation)
            {
                return 0;
            }

            switch (mDistanceMethod)
            {
                case CityDistanceMethod.Euclidean :
                    return (int) Utilitaire.EuclidianDistance(this.mLocation, city.mLocation);


                case CityDistanceMethod.EuclideanNoSQR :
                    return Utilitaire.SquareDistance(this.mLocation, city.mLocation);


                case CityDistanceMethod.Manhattan :
                    return Utilitaire.ManathanDistance(this.mLocation, city.mLocation);


                case CityDistanceMethod.PathFinderDistance :
                    return myPathManager.GetTurnCost(this.mLocation, city.mLocation, ref mPathFinderConfig);

                default:
                    // Normalement on ne passe jamais ici
					throw new Exception("Distance methode undefined");
            }            
        }

        public static int completeCircuit(List<City> nodes)
        {
            if (nodes.Count == 0)
                return 0;
            City lastNode = nodes[nodes.Count - 1];
            nodes.Add(nodes[0]);
            return lastNode.Distance(nodes[0]);
        }
    }
}
